/*
 * @Author      : ZhouQiJun
 * @Date        : 2025-08-09 02:34:34
 * @LastEditors : ZhouQiJun
 * @LastEditTime: 2025-08-09 05:06:16
 * @Description : 对象深度合并 类似 Object.assign
 */
import { isNil } from 'es-toolkit'

/**
 * 判断是否为普通对象（即由对象字面量或 Object.create(null) 创建的对象）。
 * @param obj 待判断值
 * @returns 如果是普通对象，返回 true，否则返回 false
 */
function isPlainObject(obj: unknown): obj is Record<string, unknown> {
  return Object.prototype.toString.call(obj) === '[object Object]'
}

/**
 * 递归深度合并 source 到 target。
 * - 如果属性是普通对象或数组，递归合并
 * - 否则直接覆盖
 * @param target 目标对象或数组
 * @param source 源对象或数组
 * @returns 合并后的 target
 */
function deepMerge<T>(target: T, source: unknown): T {
  if (source === null || typeof source !== 'object') {
    return source as T
  }

  if (Array.isArray(source)) {
    const arr = Array.isArray(target) ? target : []
    source.forEach((item, index) => {
      arr[index] = deepMerge(arr[index], item)
    })
    return arr as unknown as T
  }

  if (isPlainObject(source)) {
    const obj = isPlainObject(target) ? target : {}
    Object.keys(source).forEach((key) => {
      //@ts-ignore
      obj[key] = deepMerge(obj[key], source[key])
    })
    return obj as T
  }

  // 其他类型（比如函数、Date等）直接返回 source
  return source as T
}

/**
 * 深度合并多个对象或数组，类似 Object.assign，但支持递归合并。
 * @deprecated 使用 import {  merge } from 'es-toolkit' 代替
 * @param target 目标对象或数组，不能为空
 * @param sources 要合并的源对象或数组列表
 * @returns 合并后的 target，引用同入参 target
 *
 * @example
 * ```ts
 * const obj1 = { a: 1, b: { c: 2 } };
 * const obj2 = { b: { d: 3 }, e: 4 };
 * const result = assign({}, obj1, obj2);
 * // result = { a: 1, b: { c: 2, d: 3 }, e: 4 }
 * ```
 */
export default function assign<T extends object | unknown[]>(target: T, ...sources: unknown[]): T {
  if (isNil(target)) {
    return target
  }
  for (const source of sources) {
    deepMerge(target, source)
  }
  return target
}
